package com.sky.utils;

import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;

@Data
@Slf4j
@AllArgsConstructor
public class MinIoUtil {

    private String endpoint;
    private String accessKey;
    private String secretKey;
    private String bucketName;

    public String uploading(MultipartFile file) throws Exception {
        String originalFilename = file.getOriginalFilename();
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//文件后缀
        String extendName = UUID.randomUUID().toString() + suffix;
        // 将 MultipartFile 保存为临时文件
        File tempFile = File.createTempFile("minio-upload-", extendName);
        file.transferTo(tempFile);//将临时文件tmepfile转成文件路径传递给uploading

        // 调用 uploading(String filePath) 方法上传文件
        String accessUrl = uploading(tempFile.getAbsolutePath());

        // 删除临时文件
        if (tempFile.exists()) {
            tempFile.delete();
        }

        return accessUrl;
    }

    public String uploading(String filePath) throws Exception {
        // 创建 Minio 客户端
        MinioClient minioClient = MinioClient.builder()
                .credentials(accessKey, secretKey)
                .endpoint(endpoint)
                .build();

        // 获取文件名
        String fileName = new File(filePath).getName();
        if (fileName == null || fileName.isEmpty()) {
            throw new IOException("无效的文件名");
        }

        // 检查存储桶是否存在，如果不存在则创建
        boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (!isExist) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
        }

        // 上传文件
        try (FileInputStream fileInputStream = new FileInputStream(filePath)) {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object(fileName) // 文件名
                    .contentType(Files.probeContentType(Paths.get(filePath))) // 自动检测文件类型
                    .bucket(bucketName) // 存储桶名称
                    .stream(fileInputStream, fileInputStream.available(), -1) // 文件流
                    .build();
            minioClient.putObject(putObjectArgs);
        }

        // 设置存储桶策略为公开
        String bucketPolicy = "{"
                + "  \"Version\": \"2012-10-17\","
                + "  \"Statement\": ["
                + "    {"
                + "      \"Effect\": \"Allow\","
                + "      \"Principal\": \"*\","
                + "      \"Action\": [\"s3:GetObject\"],"
                + "      \"Resource\": [\"arn:aws:s3:::" + bucketName + "/*\"]"
                + "    }"
                + "  ]"
                + "}";
        minioClient.setBucketPolicy(bucketName, bucketPolicy);

        // 获取文件的访问地址（URL）
        String accessUrl = minioClient.getObjectUrl(bucketName, fileName);
        log.info("文件上传成功，访问地址: {}", accessUrl);

        // 删除临时文件
        if (Files.exists(Paths.get(filePath))) {
            try {
                Files.delete(Paths.get(filePath));
                log.info("临时文件删除成功: {}", filePath);
            } catch (IOException e) {
                log.error("删除临时文件失败", e);
            }
        } else {
            log.warn("临时文件不存在: {}", filePath);
        }

        return accessUrl;
    }
}